package com.springBoot.springBootSysCore.modules.shiro.stateles;

import com.springBoot.springBootSysCore.common.StaticConfig;
import com.springBoot.springBootSysCore.common.utils.CacheUtils;
import com.springBoot.springBootSysCore.common.utils.IdGen;
import com.springBoot.springBootSysCore.common.utils.encoding.HmacSHA256Utils;
import com.springBoot.springBootSysCore.modules.entity.system.SysUser;
import com.springBoot.springBootSysCore.modules.repository.system.SysUserRepository;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by timo on 2017/11/27.
 */
@Component
public class StatelessAuthcFilter extends AccessControlFilter {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private SysUserRepository sysUserRepository;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        return false;
    }

    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

        //1、客户端生成的消息摘要
        String clientDigest = request.getParameter(StaticConfig.PARAM_DIGEST);
        //2、客户端传入的用户身份
        String username = request.getParameter(StaticConfig.PARAM_USERNAME);


        //3、客户端请求的参数列表
        Map<String, String[]> params = new HashMap<String, String[]>(request.getParameterMap());
        params.remove(StaticConfig.PARAM_DIGEST);

        HttpServletRequest httpReq = (HttpServletRequest) request;
        String ctxPath = httpReq.getContextPath();
        String requestUri = httpReq.getRequestURI(); // 请求的全路径,比如:
        String uri = requestUri.substring(ctxPath.length());// 全路径除去ctxPath
        String tarUri = uri.trim();
        logger.info("=============app认证拦截==================");

        if (!tarUri.endsWith("/api/login/login")) {//如果是登录请求-不登录直接设置摘要并返回 但是登录要进入这里

            logger.info("=============请求路径：" + tarUri + "==================");
            logger.info("=============消息摘要：" + clientDigest + "==================");
            logger.info("=============用户身份：" + username + "==================");
//            System.out.println("=============用户数据库摘要："+u.getClientDigest()+"==================");

            if (StringUtils.isBlank(clientDigest) || StringUtils.isBlank(clientDigest)) {
                onLoginFail(response); //6、登录失败
                return false;
            }
            //4、生成无状态Token
            StatelessToken token = new StatelessToken(username, params, HmacSHA256Utils.digest(clientDigest, params));
            try {
                //5、委托给Realm进行登录
                getSubject(request, response).login(token);
                CacheUtils.remove(StaticConfig.PARAM_DIGEST + username);
            } catch (Exception e) {
                //暂不做打印
//                e.printStackTrace();
                onLoginFail(response); //6、登录失败
                return false;
            }
        }
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        if (tarUri.endsWith("/api/login/login")) {
            if (StringUtils.isBlank(username)) {
                username = request.getParameter("phone").toString();
            }
            SysUser u = sysUserRepository.findByAccount(username);
            clientDigest = IdGen.get36UUID();
            if (u != null) {
                u.setClientDigest(clientDigest);
//              //事务可能被提交
                sysUserRepository.save(u);
            }
//            CacheUtils.put(StaticConfig.PARAM_DIGEST+username,clientDigest);
//        String sql ="update SYS_USER SET  client_digest = ?";
//        jdbcTemplate.update(sql,  new Object[] {clientDigest});
        }
        httpResponse.setHeader(StaticConfig.PARAM_DIGEST, clientDigest);
        logger.info("=============app认证拦截结束==================");
        return true;
    }

    //登录失败时默认返回401状态码
    private void onLoginFail(ServletResponse response) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        httpResponse.getWriter().write("login error");
    }
}
